package com.dianshang.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.dianshang.dao.CategoryDao;
import com.dianshang.entity.PageResult;
import com.dianshang.pojo.goods.Category;
import com.dianshang.service.goods.CategoryService;
import com.dianshang.utils.RedisClient;
import com.dianshang.vo.CategoryVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private RedisClient redisClient; // Redis的客户端工具类

    /**
     * 查询所有
     */
    @Override
    public List<Category> findAll() {
        return categoryDao.selectAll();
    }

    /**
     * 查询所有+分页
     * page 页码
     * size 每页记录数
     * 分页结果
     */
    @Override
    public PageResult<Category> findPage(Integer page, Integer size) {
        PageHelper.startPage(page,size);
        Page<Category> categorys = (Page<Category>) categoryDao.selectAll();
        return new PageResult<Category>(categorys.getTotal(),categorys.getResult());
    }

    /**
     * 查询所有+模糊
     * searchMap 查询条件
     */
    @Override
    public List<Category> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return categoryDao.selectByExample(example);
    }

    /**
     * 查询所有+分页+模糊
     * searchMap
     * page
     * size
     */
    @Override
    public PageResult<Category> findPage(Map<String, Object> searchMap, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Category> categorys = (Page<Category>) categoryDao.selectByExample(example);
        return new PageResult<Category>(categorys.getTotal(),categorys.getResult());
    }

    /**
     * 回显
     * id
     */
    @Override
    public Category findById(Integer id) {
        return categoryDao.selectByPrimaryKey(id);
    }

    /**
     * 新增
     * category
     */
    @Override
    public void add(Category category) {
        categoryDao.insert(category);

        // 运行的时候就同步Redis中数据 全删
        redisClient.del("INDEX_CATEGORY_MAP"); // Hash类型
        // redisClient.del("INDEX_CATEGORY_String"); // String类型
        // 重新加载
        preLoadIndexCategoryList();
    }

    /**
     * 修改
     * category
     */
    @Override
    public void update(Category category) {
        categoryDao.updateByPrimaryKeySelective(category);

        // 运行的时候就同步Redis中数据 全删
        redisClient.del("INDEX_CATEGORY_MAP"); // Hash类型
        // redisClient.del("INDEX_CATEGORY_String"); // String类型
        // 重新加载
        preLoadIndexCategoryList();
    }

    /**
     * 删除
     * id
     */
    @Override
    public void delete(Integer id) {
        // 判断是否存在下级分类
        Example example = new Example(Category.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",id);
        int count = categoryDao.selectCountByExample(example);
        if(count > 0){
            throw new RuntimeException("存在下级分类不能删除");
        }
        categoryDao.deleteByPrimaryKey(id);

        // 运行的时候就同步Redis中数据 全删
        redisClient.del("INDEX_CATEGORY_MAP"); // Hash类型
        // redisClient.del("INDEX_CATEGORY_String"); // String类型
        // 重新加载
        preLoadIndexCategoryList();
    }

    /**
     * 查询商品分类的数据——》1级分类包含2级分类,2级分类包含3级分类(Thymeleaf实现)
     * 将商品分类加载到缓存中
     * Map——>Hash类型
     * CategoryVO——>String类型
     */
    @Override
    public List<Map> findCategoryList() { // Hash类型
    // public List<CategoryVO> findCategoryList() { // String类型
        // 从Redis中获取数据
        System.out.println("=======================================================");
        // 全部分类
        List<Map> categoryList =(List) redisClient.hvalues("INDEX_CATEGORY_MAP"); // Hash类型
        // List<CategoryVO> categoryList =(List) redisClient.get("INDEX_CATEGORY_String"); // String类型
        if (categoryList.size() <= 1){
            // 查询商品分类的数据——》1级分类包含2级分类,2级分类包含3级分类(Thymeleaf实现)
            Example example = new Example(Category.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("isShow", "1"); // 是否显示 1:显示 0:不显示
            example.setOrderByClause("seq");
            List<Category> categories = categoryDao.selectByExample(example); // 查询全部列表
            categoryList = findByParentId(categories,0); // 一级列表
            // 从数据库查询到的数据存到Redis缓存中
            redisClient.hset("INDEX_CATEGORY_MAP","商品分类缓存",categoryList); // Hash类型
            // redisClient.set("INDEX_CATEGORY_String",categoryList); // String类型
        }
        return categoryList;
    }

    /**
     * 商品分类加载到缓存
     * Map——>Hash类型
     * CategoryVO——>String类型
     */
    private List<Map> findByParentId(List<Category> categories, int parentId) { // Hash类型
    // private List<CategoryVO> findByParentId(List<Category> categories, int parentId) { // String类型
        List<Map> list = new ArrayList<>(); // Hash类型
        // List<CategoryVO> list = new ArrayList<>(); // String类型
        for (Category category : categories) {
            if (category.getParentId().equals(parentId)){
                // Hash类型
                HashMap hashMap = new HashMap();
                hashMap.put("name",category.getName()); // 分类名称
                hashMap.put("menus",findByParentId(categories,category.getId())); // 下级——比如：1级分类包含2级分类(前端页面2级分类循环：.menus),2级分类包含3级分类(前端页面3级分类循环：.menus)
                list.add(hashMap);
                /*
                CategoryVO categoryVO = new CategoryVO(); // String类型
                categoryVO.setName(category.getName()); // 分类名称
                categoryVO.setMenus(findByParentId(categories,category.getId())); // 下级——比如：1级分类包含2级分类(前端页面2级分类循环：.menus),2级分类包含3级分类(前端页面3级分类循环：.menus)
                list.add(categoryVO);
                */
            }
        }
        return list;
    }

    /**
     * 同步Redis中数据
     * Map——>Hash类型
     * CategoryVO——>String类型
     */
    @Override
    public void preLoadIndexCategoryList() {
        // 1、从MySQL中查询出分类数据
        List<Category> categories = categoryDao.selectAll();
        // 2、将数据进行了一个树状的组装
        List<Map> list = findByParentId(categories, 0); // Hash类型
        // List<CategoryVO> list = findByParentId(categories, 0); // String类型
        // 3、将数据保存到Redis
        /**
         * Hash类型
         * key1                     key2                     value
         * INDEX_CATEGORY_MAP       id                       map
         * String类型
         * key                     value
         * INDEX_CATEGORY_String       map
         */
        for (Map map : list) {
            Integer id =(Integer) map.get("id");
            redisClient.hset("INDEX_CATEGORY_MAP",id.toString(),map); // Hash类型
        }
        // redisClient.set("INDEX_CATEGORY_String",list); // String类型
    }

    /**
     * 构建查询条件
     * searchMap
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Category.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap != null){
            // 分类名称
            if(searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
            }
            // 是否显示
            if(searchMap.get("isShow")!=null && !"".equals(searchMap.get("isShow"))){
                criteria.andLike("isShow","%"+searchMap.get("isShow")+"%");
            }
            // 是否导航
            if(searchMap.get("isMenu")!=null && !"".equals(searchMap.get("isMenu"))){
                criteria.andLike("isMenu","%"+searchMap.get("isMenu")+"%");
            }
            // 分类ID
            if(searchMap.get("id")!=null ){
                criteria.andEqualTo("id",searchMap.get("id"));
            }
            // 商品数量
            if(searchMap.get("goodsNum")!=null ){
                criteria.andEqualTo("goodsNum",searchMap.get("goodsNum"));
            }
            // 排序
            if(searchMap.get("seq")!=null ){
                criteria.andEqualTo("seq",searchMap.get("seq"));
            }
            // 上级ID
            if(searchMap.get("parentId")!=null ){
                criteria.andEqualTo("parentId",searchMap.get("parentId"));
            }
            // 模板ID
            if(searchMap.get("templateId")!=null ){
                criteria.andEqualTo("templateId",searchMap.get("templateId"));
            }
        }
        return example;
    }

}